package ferp.center.server.servlet;

import com.google.appengine.api.memcache.Expiration;
import com.google.appengine.api.memcache.MemcacheService;
import com.google.appengine.api.memcache.MemcacheServiceFactory;
import ferp.center.network.RequestConfigGet;
import ferp.center.network.ResponseConfigGet;
import ferp.center.server.Action;
import ferp.center.server.entity.Config;
import ferp.center.server.messages.Messages;
import ferp.center.server.poll.Polls;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;

/**
 * User: igorgok
 * Date: 12/9/12 5:12 PM
 */
public class ConfigGet extends HttpServlet
{
  @SuppressWarnings("unchecked")
  public static Config current(EntityManager em)
  {
    MemcacheService mcs = MemcacheServiceFactory.getMemcacheService();
    Config c = (Config)mcs.get(CURRENT_CONFIG);

    if (c == null)
    {
      Query q = em.createQuery("SELECT c FROM Config c ORDER BY c.created DESC");

      q.setMaxResults(1);
      List<Config> configs = q.getResultList();

      if (configs.size() > 0)
      {
        logger.info("refreshing cached configuration");

        // get only one configuration object
        c = configs.get(0);
        // make the cache expire in 12 hours
        mcs.put(CURRENT_CONFIG, c, Expiration.byDeltaSeconds(12 * 60 * 60));
      }
    }
    else
      logger.info("using cached configuration");

    return c;
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    Action.execute(request, response, RequestConfigGet.class, new Action.Read<RequestConfigGet, ResponseConfigGet>()
    {
      @SuppressWarnings("unchecked")
      public ResponseConfigGet run(EntityManager em, RequestConfigGet input) throws IOException
      {
        ResponseConfigGet result = new ResponseConfigGet();
        Config config = current(em);

        if (config != null)
        {
          result.id = config.getId();
          result.bidding = new ResponseConfigGet.Bidding();
          result.bidding.enable = config.getBidNNEnabled();
          result.bidding.threshold = config.getBidNNThreshold();

          logger.info("configuration ID: old=[" + input.id + "], current=[" + result.id + "]");

          // only if enabled and needs to be updated
          if (result.bidding.enable && input.id != result.id)
            result.bidding.nnj = config.getBidNNJson();

          // only if levels remote updating enabled
          if (config.getLevelsEnabled())
          {
            result.levels = new ResponseConfigGet.Levels();
            result.levels.data = config.getLevelsData();
          }

          // messages support starts from version 38
          if (input.version != null && input.version.code > 37 && config.getMessagesEnabled())
            result.messages = Action.gson().toJson(Messages.get(input.locale, input.version.code, input.date));

          // get interstitial flag
          result.ad = config.getAd();
        }

        result.poll = Polls.get(input.locale, input.lastPollID);

        return result;
      }
    });
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    doPost(request, response);
  }

  // memcached key for the current configuration object
  private static final String CURRENT_CONFIG = "current-config";
  // logger
  private static final Logger logger = Logger.getLogger(ConfigGet.class.getSimpleName());
}
